package com.skivingcloud.report.service.impl;

import com.skivingcloud.report.config.HikariPoolProperties;
import com.skivingcloud.report.dto.DataSourceDto;
import com.skivingcloud.report.service.JdbcService;
import com.zaxxer.hikari.pool.HikariPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class JdbcServiceImpl implements JdbcService {
    private static final Logger log = LoggerFactory.getLogger(JdbcServiceImpl.class);
    private HikariPoolProperties hikariPoolProperties;

    public JdbcServiceImpl(HikariPoolProperties hikariPoolProperties) {
        this.hikariPoolProperties = hikariPoolProperties;
    }
    /**
     * 所有数据源的连接池存在map里
     */
    private Map<String, HikariPool> map = new ConcurrentHashMap<>();

    private Object lock = new Object();

    @Override
    public void removeJdbcConnectionPool(String id) {
        try {
            HikariPool pool = map.get(id);
            if (pool != null) {
                log.info("remove pool success, datasourceId:{}", id);
                map.remove(id);
            }
        } catch (Exception e) {
            log.error("error", e);
        }
    }

    /**
     * 获取连接
     * @param dataSource 数据源
     * @return 连接
     */
    @Override
    public Connection getPooledConnection(DataSourceDto dataSource) throws SQLException {
        HikariPool pool = getJdbcConnectionPool(dataSource);
        return pool.getConnection();
    }

    /**
     * 测试数据库连接  获取一个连接
     * @param dataSource 数据源
     * @return 连接
     */
    @Override
    public Connection getUnPooledConnection(DataSourceDto dataSource) throws SQLException {
        HikariPool hikariDataSource = hikariPoolProperties.dataSource(dataSource.getJdbcUrl(),
                dataSource.getUsername(), dataSource.getPassword(), dataSource.getDriverName());
        return hikariDataSource.getConnection();
    }

    public HikariPool getJdbcConnectionPool(DataSourceDto dataSource) {
        if (!map.containsKey(dataSource.getId())) {
            synchronized (lock) {
                if (!map.containsKey(dataSource.getId())) {
                    HikariPool pool = hikariPoolProperties.dataSource(dataSource.getJdbcUrl(),
                            dataSource.getUsername(), dataSource.getPassword(), dataSource.getDriverName());
                    map.put(dataSource.getId(), pool);
                    log.info("创建连接池成功：{}", dataSource.getJdbcUrl());
                }
            }
        }
        return map.get(dataSource.getId());
    }
}
